#!/usr/bin/env ts-node
/**
 * Prompt解析器
 * 用于解析用户Prompt中的YAML配置和提取组件信息
 */

import * as yaml from 'js-yaml';
import * as fs from 'fs';
import * as path from 'path';

const getErrorMessage = (error: unknown): string => {
  if (error instanceof Error) {
    return error.message;
  }
  if (typeof error === 'string') {
    return error;
  }
  try {
    return JSON.stringify(error);
  } catch {
    return String(error);
  }
};

interface ComponentConfig {
  Component: {
    name: string;
    displayName: string;
    group: string;
    subGroup: string;
    platform?: string;
    description?: string;
  };

  Figma: {
    main_url: string;
    content_panel_url?: string;
    style_panel_url?: string;
    themes?: Record<string, string>;
    auxiliary?: Record<string, string>;
  };

  Document: {
    requirements?: string;
    solution?: string;
    specification?: string;
    fallback_data?: string;
  };

  Implementation?: {
    constraints?: string[];
    features?: string[];
    excludes?: string[];
    priority?: string;
  };

  Output?: {
    root?: string;
    format?: string;
  };
}

interface ParsedPrompt {
  config: ComponentConfig;
  textContent: string;
  metadata: {
    timestamp: string;
    parser: string;
    version: string;
  };
}

class PromptParser {

  /**
   * 解析Prompt内容
   */
  parsePrompt(promptContent: string): ParsedPrompt {
    // 提取YAML部分
    const yamlMatch = promptContent.match(/```yaml\n([\s\S]*?)\n```/);
    if (!yamlMatch) {
      throw new Error('No YAML configuration found in prompt');
    }

    const yamlContent = yamlMatch[1];

    // 解析YAML
    let config: ComponentConfig;
    try {
      config = yaml.load(yamlContent) as ComponentConfig;
    } catch (error) {
      throw new Error(`Failed to parse YAML: ${getErrorMessage(error)}`);
    }

    // 验证必需字段
    this.validateConfig(config);

    // 提取文本内容（YAML之外的部分）
    const textContent = promptContent
      .replace(/```yaml[\s\S]*?```/, '')
      .trim();

    return {
      config,
      textContent,
      metadata: {
        timestamp: new Date().toISOString(),
        parser: 'PromptParser',
        version: '1.0.0'
      }
    };
  }

  /**
   * 验证配置完整性
   */
  private validateConfig(config: ComponentConfig): void {
    // 验证Component部分
    if (!config.Component) {
      throw new Error('Missing Component configuration');
    }
    if (!config.Component.name) {
      throw new Error('Component.name is required');
    }
    if (!config.Component.displayName) {
      throw new Error('Component.displayName is required');
    }

    // 验证Figma部分
    if (!config.Figma) {
      throw new Error('Missing Figma configuration');
    }
    if (!config.Figma.main_url) {
      throw new Error('Figma.main_url is required');
    }

    // 验证URL格式
    this.validateFigmaUrl(config.Figma.main_url);

    if (config.Figma.content_panel_url) {
      this.validateFigmaUrl(config.Figma.content_panel_url);
    }

    if (config.Figma.style_panel_url) {
      this.validateFigmaUrl(config.Figma.style_panel_url);
    }
  }

  /**
   * 验证Figma URL格式
   */
  private validateFigmaUrl(url: string): void {
    // 检查是否包含node-id
    if (!url.includes('node-id=') && !url.includes('node_id=')) {
      throw new Error(`Figma URL must contain node-id: ${url}`);
    }

    // 提取fileKey和nodeId
    const fileKeyMatch = url.match(/\/(?:file|design)\/([a-zA-Z0-9]+)/);
    if (!fileKeyMatch) {
      throw new Error(`Invalid Figma URL format: ${url}`);
    }
  }

  /**
   * 提取Figma参数
   */
  extractFigmaParams(url: string): { fileKey: string; nodeId: string } {
    const fileKeyMatch = url.match(/\/(?:file|design)\/([a-zA-Z0-9]+)/);
    const nodeIdMatch = url.match(/node-id=([^&]+)/);

    if (!fileKeyMatch || !nodeIdMatch) {
      throw new Error('Failed to extract Figma parameters');
    }

    return {
      fileKey: fileKeyMatch[1],
      nodeId: nodeIdMatch[1].replace(/-/g, ':')
    };
  }

  /**
   * 生成执行上下文
   */
  generateExecutionContext(parsed: ParsedPrompt): any {
    const { config } = parsed;
    const mainParams = this.extractFigmaParams(config.Figma.main_url);

    const context = {
      component: {
        name: config.Component.name,
        displayName: config.Component.displayName,
        group: config.Component.group,
        subGroup: config.Component.subGroup,
        platform: config.Component.platform || 'H5',
        description: config.Component.description || ''
      },
      figma: {
        fileKey: mainParams.fileKey,
        nodeId: mainParams.nodeId,
        mainUrl: config.Figma.main_url,
        contentPanelUrl: config.Figma.content_panel_url,
        stylePanelUrl: config.Figma.style_panel_url,
        themes: config.Figma.themes || {},
        auxiliary: config.Figma.auxiliary || {}
      },
      documents: config.Document || {},
      implementation: config.Implementation || {},
      output: {
        root: config.Output?.root || `./${config.Component.name}`,
        format: config.Output?.format || 'typescript'
      },
      metadata: parsed.metadata,
      userInstructions: parsed.textContent
    };

    return context;
  }

  /**
   * 识别组件模式
   */
  identifyComponentPatterns(config: ComponentConfig): string[] {
    const patterns: string[] = [];

    // 基于组名识别
    const name = config.Component.name.toLowerCase();

    if (name.includes('dashboard') || name.includes('trend')) {
      patterns.push('dashboard');
    }
    if (name.includes('chart') || name.includes('graph')) {
      patterns.push('visualization');
    }
    if (name.includes('form') || name.includes('input')) {
      patterns.push('form');
    }
    if (name.includes('list') || name.includes('table')) {
      patterns.push('data-display');
    }
    if (name.includes('modal') || name.includes('dialog')) {
      patterns.push('overlay');
    }

    // 基于分组识别
    if (config.Component.group === 'Telecom') {
      patterns.push('telecom-specific');
    }

    // 基于平台识别
    if (config.Component.platform === 'Mobile') {
      patterns.push('mobile-optimized');
    }

    return patterns;
  }

  /**
   * 保存解析结果
   */
  saveParseResult(parsed: ParsedPrompt, outputDir: string): void {
    const outputPath = path.join(outputDir, 'phase0');

    if (!fs.existsSync(outputPath)) {
      fs.mkdirSync(outputPath, { recursive: true });
    }

    // 保存执行上下文
    const context = this.generateExecutionContext(parsed);
    fs.writeFileSync(
      path.join(outputPath, 'execution-context.json'),
      JSON.stringify(context, null, 2)
    );

    // 保存原始配置
    fs.writeFileSync(
      path.join(outputPath, 'prompt-config.json'),
      JSON.stringify(parsed.config, null, 2)
    );

    // 保存识别的模式
    const patterns = this.identifyComponentPatterns(parsed.config);
    fs.writeFileSync(
      path.join(outputPath, 'identified-patterns.json'),
      JSON.stringify({
        patterns,
        confidence: patterns.length > 0 ? 0.8 : 0.5,
        source: 'PromptParser'
      }, null, 2)
    );

    console.log(`✅ Parse results saved to ${outputPath}`);
  }
}

// CLI执行
if (require.main === module) {
  const args = process.argv.slice(2);

  if (args.length < 1) {
    console.error('Usage: ts-node prompt-parser.ts <prompt-file> [output-dir]');
    process.exit(1);
  }

  const promptFile = args[0];
  const outputDir = args[1] || process.cwd();

  if (!fs.existsSync(promptFile)) {
    console.error(`Prompt file not found: ${promptFile}`);
    process.exit(1);
  }

  const parser = new PromptParser();

  try {
    const promptContent = fs.readFileSync(promptFile, 'utf-8');
    const parsed = parser.parsePrompt(promptContent);

    console.log('📋 Parsed Component:', parsed.config.Component.name);
    console.log('🎨 Figma URL:', parsed.config.Figma.main_url);

    const patterns = parser.identifyComponentPatterns(parsed.config);
    if (patterns.length > 0) {
      console.log('🔍 Identified Patterns:', patterns.join(', '));
    }

    parser.saveParseResult(parsed, outputDir);

    console.log('✅ Prompt parsing completed successfully');
  } catch (error) {
    console.error('❌ Parsing failed:', getErrorMessage(error));
    process.exit(1);
  }
}

export { PromptParser, ComponentConfig, ParsedPrompt };
